package com.restphp.java.utils.mysql.builder.core;

import com.restphp.java.utils.mysql.builder.enums.ExpressEnum;
import com.restphp.java.utils.mysql.builder.po.NativePo;
import com.restphp.java.utils.mysql.builder.po.QueryPo;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * SQL条件拼接对象.
 * Created by sofical on 2020/6/12.
 */
public class SqlConditionUtils {
    private List<QueryPo> conditionDoList = new ArrayList<>();

    /**
     * 添加条件.
     * @param column 列名.
     * @param express 表达式.
     * @param value 值.
     * @return SQL条件拼接对象.
     */
    public SqlConditionUtils add(String column, ExpressEnum express, Object value) {
        QueryPo conditionDo = new QueryPo();
        conditionDo.setColumn(column);
        conditionDo.setExpress(express);
        conditionDo.setValue(value);
        this.conditionDoList.add(conditionDo);
        return this;
    }

    /**
     * 添加等于条件.
     * @param column 列名.
     * @param value 值.
     * @return SQL条件拼接对象.
     */
    public SqlConditionUtils add(String column, Object value) {
        return this.add(column, ExpressEnum.EQ, value);
    }

    /**
     * 兼容旧模式条件组合.
     * @param cdt 条件Map.
     * @return SQL条件拼接对象.
     */
    public SqlConditionUtils add(Map<String, Object> cdt) {
        for (Map.Entry<String, Object> entry : cdt.entrySet()) {
            this.add(entry.getKey(), ExpressEnum.EQ, entry.getValue());
        }
        return this;
    }

    /**
     * 获取SQL拼接结果.
     * @return 拼接结果对象.
     */
    public NativePo getWhere() {
        NativePo result = new NativePo();
        StringBuilder sql = new StringBuilder("");
        List<Object> values = new ArrayList<>();
        Integer i = 0;
        for (QueryPo conditionDo : this.conditionDoList) {
            if (i > 0) {
                sql.append(" and ");
            }
            if (ExpressEnum.NATIVE.equals(conditionDo.getExpress())) {
                NativePo nativeDo = (NativePo) conditionDo.getValue();
                sql.append(nativeDo.getSql());
                values.addAll(nativeDo.getValues());
            } else {
                sql.append(conditionDo.getColumn()).append(" ").append(conditionDo.getExpress().getMatch()).append(" ");

                if (ExpressEnum.IN.equals(conditionDo.getExpress()) ||
                        ExpressEnum.NIN.equals(conditionDo.getExpress())) {
                    //in 或 not in 占位符需要根据查询值特殊处理.
                    //sql.append("(:").append(paramName).append(")");
                    sql.append("(");
                    List<Object> inValues = (List<Object>) conditionDo.getValue();
                    String inValSpace = "";
                    for (Object val : inValues) {
                        inValSpace += ("".equals(inValSpace) ? "" : ",") + "?";
                        values.add(val);
                    }
                    sql.append(inValSpace).append(")");
                } else {
                    sql.append("?");
                    values.add(conditionDo.getValue());
                }
                //values.put(paramName, conditionDo.getValue());
            }
            ++i;
        }
        result.setSql(sql.toString());
        result.setValues(values);
        return result;
    }
}
